package fun.hijklmn.magic.admin.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import fun.hijklmn.magic.admin.common.pojo.Permission;
import fun.hijklmn.magic.admin.common.pojo.RolePermission;
import fun.hijklmn.magic.admin.common.vo.resp.BtnPermissionRespVO;
import fun.hijklmn.magic.admin.common.vo.resp.DirPermissionRespVO;
import fun.hijklmn.magic.admin.common.vo.resp.LinkPermissionRespVO;
import fun.hijklmn.magic.admin.server.constants.RedisKeyConstant;
import fun.hijklmn.magic.admin.server.dao.RolePermissionDao;
import fun.hijklmn.magic.admin.server.enums.PermissionTypeEnum;
import fun.hijklmn.magic.admin.server.service.PermissionService;
import fun.hijklmn.magic.admin.server.service.RolePermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zsl
 * @since 2021-06-25
 */
@Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionDao, RolePermission> implements RolePermissionService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Override
    public List<DirPermissionRespVO> queryPermissionCacheByRoleId(String roleId) {

        List<DirPermissionRespVO> dirPermissionRespVOList = (List<DirPermissionRespVO>) redisTemplate.opsForValue().get(RedisKeyConstant.roleId_Permissions.concat(roleId));

        if (CollectionUtils.isEmpty(dirPermissionRespVOList)) {

            QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
            rolePermissionQueryWrapper.eq("is_delete", 0);
            rolePermissionQueryWrapper.eq("role_id", roleId);
            rolePermissionQueryWrapper.select("permission_id");
            List<RolePermission> rolePermissions = rolePermissionService.list(rolePermissionQueryWrapper);

            List<String> permissionIds = rolePermissions.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(permissionIds)) {

                QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
                permissionQueryWrapper.eq("is_delete", 0);
                permissionQueryWrapper.in("id", permissionIds);
                permissionQueryWrapper.select("id", "name", "type", "icon", "request_url", "parent_id");
                List<Permission> permissionList = permissionService.list(permissionQueryWrapper);

                Map<String, List<Permission>> permissionListMap = permissionList.stream().filter(permission -> StringUtils.isNotEmpty(permission.getParentId())).collect(Collectors.groupingBy(Permission::getParentId));

                List<DirPermissionRespVO> dirPermissionRespVOList1 = Lists.newArrayList();

                permissionList.stream().filter(permission -> PermissionTypeEnum.dir.type().intValue() == permission.getType()).forEach(permission -> {
                    DirPermissionRespVO dirPermissionRespVO = new DirPermissionRespVO();
                    BeanUtils.copyProperties(permission, dirPermissionRespVO);
                    if (permissionListMap.containsKey(dirPermissionRespVO.getId())) {
                        List<Permission> permissionList1 = permissionListMap.get(dirPermissionRespVO.getId());
                        List<LinkPermissionRespVO> linkPermissionRespVOList = Lists.newArrayList();
                        permissionList1.stream().filter(permission1 -> PermissionTypeEnum.link.type().intValue() == permission1.getType()).forEach(permission1 -> {
                            LinkPermissionRespVO linkPermissionRespVO = new LinkPermissionRespVO();
                            BeanUtils.copyProperties(permission1, linkPermissionRespVO);
                            if (permissionListMap.containsKey(permission1.getId())) {
                                List<BtnPermissionRespVO> btnPermissionRespVOList = Lists.newLinkedList();
                                List<Permission> permissionList2 = permissionListMap.get(permission1.getId());
                                permissionList2.stream().filter(permission2 -> PermissionTypeEnum.btn.type().intValue() == permission2.getType()).forEach(permission2 -> {
                                    BtnPermissionRespVO btnPermissionRespVO = new BtnPermissionRespVO();
                                    BeanUtils.copyProperties(permission2, btnPermissionRespVO);
                                    btnPermissionRespVOList.add(btnPermissionRespVO);
                                });
                                linkPermissionRespVO.setBtnPermissionRespVOList(btnPermissionRespVOList);
                            }
                            linkPermissionRespVOList.add(linkPermissionRespVO);
                        });
                        dirPermissionRespVO.setLinkPermissionRespVOList(linkPermissionRespVOList);
                    }
                    dirPermissionRespVOList1.add(dirPermissionRespVO);

                });

                if (CollectionUtils.isNotEmpty(dirPermissionRespVOList1)) {
                    dirPermissionRespVOList = dirPermissionRespVOList1;
                    redisTemplate.opsForValue().set(RedisKeyConstant.roleId_Permissions.concat(roleId), dirPermissionRespVOList);
                }

            }

        }

        return dirPermissionRespVOList;

    }

}
